/* Copyright 2011 Tobias Marschall, Email: tm@cwi.nl 
 * 
 * This file is part of string-cover.
 *
 * string-cover is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * string-cover is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with string-cover.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MULTIPLIERS_H_
#define MULTIPLIERS_H_

#include <iostream>
#include <valarray>
#include <string>
#include <boost/dynamic_bitset.hpp>

#include "ProblemInstance.h"
#include "IntervalNumbering.h"

/** Represents a set of Lagrangian multipliers, i.e. one multiplier for each
 *  interval. */
class Multipliers {
private:
	const ProblemInstance& instance;
	std::valarray<double> values;
	Multipliers(const ProblemInstance& instance, const std::valarray<double>& values);
public:
	/** Initializes multipliers to w_t/n_t, where w_t is the weight of substring t and
	 *  n_t is the total number of occurrences of t. */
	Multipliers(const ProblemInstance& instance);
	/** Copy constructor. */
	explicit Multipliers(const Multipliers& mulipliers);
	virtual ~Multipliers();

	/** Returns multiplier for the interval of strings[string_nr] that spans from
	 *  start_pos (inclusively) to end_pos (exclusively). */
	virtual double get(size_t string_nr, size_t start_pos, size_t end_pos) const;
	virtual void set(size_t string_nr, size_t start_pos, size_t end_pos, double value);

	/** Adapt multipliers using subgradient method. Returns 0 if all gradients are zero. */
	virtual std::auto_ptr<Multipliers> adapt(double mu, double upper_bound, double lower_bound, const boost::dynamic_bitset<>& selected_substrings, const boost::dynamic_bitset<>& selected_intervals) const;
	/** Writes the sum of multipliers for each substring to a given array, i.e. for each substring
	 *  the multipliers of all intervals equal to it are summed up. */
	virtual void multiplierSums(double* result_array);

    friend std::ostream& operator<<(std::ostream& os, const Multipliers& multipliers);
};

#endif /* MULTIPLIERS_H_ */
